package com.loyal.rx;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observer;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;

public class RxPermission {
    private RxPermissions rxPermissions;
    private Disposable disposable;
    private static RxPermission rxPer;

    public static RxPermission getInstance() {
        if (null == rxPer) {
            synchronized (RxPermission.class) {
                if (null == rxPer)
                    rxPer = new RxPermission();
            }
        }
        return rxPer;
    }

    public RxPermission() {
    }

    public RxPermission with(FragmentActivity activity) {
        if (null == rxPermissions)
            rxPermissions = new RxPermissions(activity);
        return this;
    }

    public RxPermission with(Fragment fragment) {
        if (null == rxPermissions)
            rxPermissions = new RxPermissions(fragment);
        return this;
    }

    /**
     * 建议使用{@link #multiple(MultipleCallback, String...)}
     */
    public void single(int code, final SingleCallback listener, String... permissions) {
        rxPermissions.request(permissions)
                .safeSubscribe(new Observer<Boolean>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onNext(@NonNull Boolean aBoolean) {
                        if (null != listener)
                            listener.onSingleCallback(code, aBoolean, null);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        if (null != listener)
                            listener.onSingleCallback(code, false, e);
                        dispose();
                    }

                    @Override
                    public void onComplete() {
                        dispose();
                    }
                });
    }

    public void multiple(final MultipleCallback listener, String... permissions) {
        List<String> refuseList = new ArrayList<>();
        List<String> rationaleList = new ArrayList<>();
       /* disposable = rxPermissions.requestEach(permissions)
                .filter(permission -> !permission.granted)//过滤掉已经授权的权限
                .toList().subscribe(permissionList -> {
                    for (Permission permission : permissionList) {
                        boolean granted = permission.granted;
                        String name = permission.name;
                        boolean rationale = permission.shouldShowRequestPermissionRationale;
                        if (!rationale) {
                            rationaleList.add(name);
                        }
                        if (!granted && !rationaleList.contains(name)) {
                            refuseList.add(name);
                        }
                    }
                    if (null != listener)
                        listener.onMultipleCallback(refuseList, rationaleList);
                    Log.e("request: ", "--end--");
                    dispose();
                });*/
        rxPermissions.requestEach(permissions)
                .filter(permission -> !permission.granted)//过滤掉已经授权的权限
                .toList().subscribe(new SingleObserver<List<Permission>>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                disposable = d;
            }

            @Override
            public void onSuccess(@NonNull List<Permission> permissionList) {
                for (Permission permission : permissionList) {
                    boolean granted = permission.granted;
                    String name = permission.name;
                    boolean rationale = permission.shouldShowRequestPermissionRationale;
                    if (!rationale) {
                        rationaleList.add(name);
                    }
                    if (!granted && !rationaleList.contains(name)) {
                        refuseList.add(name);
                    }
                }
                if (null != listener)
                    listener.onMultipleCallback(refuseList, rationaleList, null);
                dispose();
            }

            @Override
            public void onError(@NonNull Throwable e) {
                if (null != listener)
                    listener.onMultipleCallback(refuseList, rationaleList, e);
                dispose();
            }
        });
    }

    private void dispose() {
        if (null != disposable && !disposable.isDisposed()) {
            disposable.dispose();
        }
        if (null != rxPermissions)
            rxPermissions = null;
    }

    public interface MultipleCallback {
        /**
         * if(successful){
         * // `singlePermission.name` is granted !
         * //成功获取权限 do something
         * }else if(shouldShow){
         * <p>
         * //本次拒绝，下次接着弹窗提示请求
         * }else{
         * //权限申请被拒，下次也不会弹窗提示
         * }
         *
         * @param refuseList    拒绝权限列表
         * @param rationaleList 拒绝后不再询问列表
         */
        void onMultipleCallback(@NonNull List<String> refuseList,
                                @NonNull List<String> rationaleList,
                                @Nullable Throwable e);
    }

    public interface SingleCallback {
        void onSingleCallback(int code, boolean successful, @Nullable Throwable e);
    }
}
